﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace Twitter.Tests
{
    [TestFixture]
    public class ListMessageBuilderFixture
    {
        [Test]
        public void ShouldGenerateNoMessages()
        {
            var builder = new ListMessageBuilder();
            Assert_Elements(new string[] { }, builder.GetMessages());
        }

        [Test]
        public void ShouldGenerateOneMessageIfLessThanMaxLength()
        {
            var fragment1 = "Lorem ipsum dolor sit amet.";
            var builder = new ListMessageBuilder();
            builder.AppendFragment(fragment1);
            Assert_Elements(new string[]{fragment1}, builder.GetMessages());
        }


        [Test]
        public void ShouldClearAppendedFragments()
        {
            var builder = new ListMessageBuilder();
            builder.AppendFragment("Lorem ipsum dolor sit amet.");
            builder.Clear();
            Assert_Elements(new string[] { }, builder.GetMessages());
        }

        [Test]
        public void ShouldGenerateOneMessageIfLessThanMaxLengthForManyFragments()
        {
            var fragment1 = "Lorem ipsum dolor sit amet.\n";
            var fragment2 = "Donec faucibus velit eget purus.";
            var builder = new ListMessageBuilder();
            builder.AppendFragment(fragment1);
            builder.AppendFragment(fragment2);
            Assert_Elements(new string[] { fragment1 + fragment2 }, builder.GetMessages());
        }

        [Test]
        public void ShouldSplitFragmentIfNotFit()
        {
            var fragment1 = "Lorem ipsum dolor sit amet.\n";
            var fragment2 = "Donec faucibus velit eget purus.";
            var builder = new ListMessageBuilder(40);
            builder.AppendFragment(fragment1);
            builder.AppendFragment(fragment2);
            Assert_Elements(new string[] { fragment1 , fragment2 }, builder.GetMessages());            
        }

        [Test]
        public void ShouldAlwaysSendAtLeastOneEntireFragment()
        {
            var fragment1 = "Lorem ipsum dolor sit amet.\n";
            var fragment2 = "Donec faucibus velit eget purus.";
            var builder = new ListMessageBuilder(4);
            builder.AppendFragment(fragment1);
            builder.AppendFragment(fragment2);
            Assert_Elements(new string[] { fragment1, fragment2 }, builder.GetMessages());
        }

        private static void Assert_Elements<T>(IEnumerable<T> expected, IEnumerable<T> actual)
        {
            var exp = new List<T>(expected);
            var act = new List<T>(actual);
            var exp_it = exp.GetEnumerator();
            var act_it = act.GetEnumerator();
            while (exp_it.MoveNext() && act_it.MoveNext())
            {
                Assert.AreEqual(exp_it.Current, act_it.Current);
            }
            Assert.AreEqual(exp.Count, act.Count);
        }

    }
}
